package smashedapples.controls.progressbars
{
	import mx.controls.ProgressBar;
	import mx.core.Container;
	import mx.core.IFlexDisplayObject;
	import mx.core.UIComponent;
	import mx.managers.PopUpManager;
	import mx.rpc.AsyncResponder;
	import mx.rpc.AsyncToken;


	public class AsyncTokenProgressBar extends ProgressBar
	{

		public static function show( token:AsyncToken, parent:UIComponent, label:String = null ):void
		{
			var container:AsyncTokenProgressBarContainer = new AsyncTokenProgressBarContainer();
			container.height = parent.height;
			container.width = parent.width;

			var bar:AsyncTokenProgressBar = new AsyncTokenProgressBar();

			parent.callLater( bar.doShowLater, [ token, parent, container, label ]);
		}

		// the easiest way to align the asyncTokenProgressBarContainer with the parent was to call centerPopup after the parent has been rendered/displayed.
		private function doShowLater( token:AsyncToken, parent:UIComponent, container:AsyncTokenProgressBarContainer, label:String = null ):void
		{
			if( label != null )
				this.label = label;

			container.addChild( this );

			PopUpManager.addPopUp( container, parent, false );
			PopUpManager.centerPopUp( container );

			if( parent is Container && ( parent as Container ).enabled == true )
			{
				( parent as Container ).enabled = false;
				token[ "parentWasDisabledByAsyncBar" ] = true;
				token[ "parentReference" ] = parent;
			}

			this.start( token );
		}



		public function AsyncTokenProgressBar()
		{
			super();
			this.indeterminate = true;
			this.mode = "manual";
			this.maximum = 0;
			this.minimum = 0;
			this.label = "";
		}


		public function start( token:AsyncToken ):void
		{
			this.setProgress( 0, 1 );
			var responder:AsyncResponder = new AsyncResponder( handler, handler );
			token.addResponder( responder );
		}

		public function stop():void
		{
			this.setProgress( 1, 1 );

			if(( this.parent as Container ).isPopUp )
				PopUpManager.removePopUp( this.parent as IFlexDisplayObject );
		}

		//AsyncResponder fault and result handler
		private function handler( data:Object, token:Object = null ):void
		{
			if( token == null && data.hasOwnProperty( "token" ))
				token = data[ "token" ];

			if( shouldReEnableParent( token ))
			{
				( token[ "parentReference" ] as Container ).enabled = true;
			}

			stop();
		}

		private function shouldReEnableParent( token:Object ):Boolean
		{
			if( !token )
				return false;

			if( !token.hasOwnProperty( "parentWasDisabledByAsyncBar" ))
				return false;

			if( !token.hasOwnProperty( "parentReference" ))
				return false;

			if( token[ "parentWasDisabledByAsyncBar" ] == false )
				return false;

			if( !( token[ "parentReference" ] is Container ))
				return false;

			return true;
		}






	}
}